资源
正文
117-路由的简介
Note
Vue-router是 Vue 的一个插件库,专门用来实现 SPA(单页面应用)。
对 SPA 应用的理解
- 单页 Web 应用(single page web application,SPA)
- 整个应用只有一个完整的页面。
- 点击页面中的导航链接不会刷新页面,只会做页面的局部更新。
- 数据需要通过 ajax 请求获取。
路由的理解
- 什么是路由?
- 一个路由就是一组映射关系(key-value)
- key 为路径,value 可能是 function 或 component
- 路由分类
- 后端路由
- 理解:value 是 function,用于处理客户端提交的请求。
- 工作过程:服务器接收到一个请求时,根据请求路径找到匹配的函数来处
理请求,返回响应数据。
- 前端路由
- 理解:value 是 component,用于展示页面内容。
- 工作过程:当浏览器的路径改变时,对应的组件就会显示。
对于 Vue2,使用如下命令进行安装:
1
| npm install vue-router@3
|
118-路由基本使用
进入调试页面如果出现的是 http://localhost:8080/#/
而不是 http://localhost:8080/
即为路由设置成功。
119-几个注意点
Note
- 路由组件通常存放在
pages
文件夹,一般组件通常存放在 components
文件夹。
- 通过切换,“隐藏”了的路由组件,默认是被销毁掉的,需要的时候再去挂载。
- 每个组件都有自己的
$route
属性,里面存储着自己的路由信息。
- 整个应用只有一个
router
,可以通过组件的 $router
属性获取到。
120-多级(嵌套)路由
121-路由的 query 参数
122 命名路由
Note
-
作用:可以简化路由的跳转。
-
如何使用
-
给路由命名:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| { path: "demo", component: Demo, children: [ { path: "test", component: Test, children: [ { name: "Hello", path: "welcome", component: Hello, } ] } ] }
|
-
简化跳转:
1 2 3 4 5 6 7 8 9 10
| <!--简化前,需要写完整的路径 --> <router-link to="/demo/test/welcome">跳转</router-link> <!--简化后,直接通过名字跳转--> <router-link :to="{name:'hello’}">跳转</router-link> <!--简化写法配合传递参数--> <router-link :to="{name:'hello', query:{id:666, title:'你好'}" >跳转</router-link>
|
123 路由的 params 参数
修改路由的 para
:
1 2 3 4 5 6 7
| children: [ { name: 'detail', path: 'detail/:id/:title', component: Detail, } ]
|
切换路由时使用的属性改为 params
而不是 query
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <template> <div> <ul> <li v-for="m in messageList" :key="m.id"> <router-link :to="{ name: 'detail', params: { id: m.id, title: m.title } }">{{ m.title }}</router-link> </li> </ul> <hr> <router-view></router-view> </div> </template>
|
接收消息时使用 params
而不是 query
:
1 2 3 4 5 6 7 8 9 10
| <template> <ul> <li> 消息编号:{{$route.params.id}} </li> <li> 消息标题:{{$route.params.title}} </li> </ul> </template>
|
Important
特别注意:路由携带 params
参数时,若使用 to
的对象写法,则不能使用 path
配置项,必须使用 name
配置!
124 路由的 props 配置
Note
作用:让路由组件更方便的收到参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| { name: "xiangging", path: "detail/:id", component: Detail, props(route){ return{ id:route.query.id, title:route.query.title } }
|
接收参数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <template> <ul> <li> 消息编号:{{ id }} </li> <li> 消息标题:{{ title }} </li> </ul> </template>
<script> /* eslint-disable vue/multi-word-component-names */ export default { name: 'Detail', props: { id: { type: String, required: true }, title: { type: String, required: true } } } </script>
|
125 router-link 的 replace 属性
Note
- 作用:控制路由跳转时操作浏览器历史记录的模式
- 浏览器的历史记录有两种写入方式:分别为
push
和 replace
,push
是追加历史记录(追加栈),replace
是替换当前记录(栈顶)。路由跳转时候默认为 push
- 如何开启
replace
模式:<router-linkreplace.......>News</router-link>
126 编程式路由导航
Note
作用:不借助 <router-link>
实现路由跳转,让路由跳转更加灵活。
Message.vue
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| <template> <div> <ul> <li v-for="m in messageList" :key="m.id"> <router-link :to="{ name: 'detail', params: { id: m.id, title: m.title } }">{{ m.title }}</router-link> <button @click="pushShow(m)">push 查看</button> <button @click="replaceShow(m)">replace 查看</button> </li> </ul> <hr> <router-view></router-view> </div> </template>
<script> /* eslint-disable vue/multi-word-component-names */ export default { name: 'Message', data() { return { messageList: [ { id: '001', title: 'message001' }, { id: '002', title: 'message002' }, { id: '003', title: 'message003' } ] } }, methods: { pushShow(m) { // 检查当前路由是否与目标路由相同 if (this.$route.name !== 'detail' || this.$route.params.id !== m.id) { this.$router.push({ name: 'detail', params: { id: m.id, title: m.title } }); } }, replaceShow(m) { // 检查当前路由是否与目标路由相同 if (this.$route.name !== 'detail' || this.$route.params.id !== m.id) { this.$router.replace({ name: 'detail', params: { id: m.id, title: m.title } }); } } }
} </script>
|
Banner.vue
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <template> <ul> <li> 消息编号:{{ id }} </li> <li> 消息标题:{{ title }} </li> </ul> </template>
<script> /* eslint-disable vue/multi-word-component-names */ export default { name: 'Detail', props: { id: { type: String, required: true }, title: { type: String, required: true } } } </script>
|
127 缓存路由组件
Note
在切换路由时,原组件会被销毁,如果不想这么做,得使用缓存路由组件。
1 2 3
| <keep-alive inclue="News"> <router-view></router-view> </keep-alive>
|
包含多个组件:
1 2 3
| <keep-alive inclue="['News', 'Message']"> <router-view></router-view> </keep-alive>
|
128 两个新的生命周期
1 2 3 4 5 6 7 8 9 10 11 12
| activated() { console.log('News 组件被激活了') this.timer = setInterval(() => { console.log('@') this.opacity -= 0.01 if(this.opacity <= 0) this.opacity = 1 }, 16) }, deactived() { console.log('News 组件失活了') clearInterval(this.timer) }
|
Note
- 作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态。
- 具体名字:
activated
路由组件被激活时触发。
deactivated
路由组件失活时触发。
129 全局前置-路由守卫
Note
- 作用:对路由进行权限控制
- 分类:全局守卫、独享守卫、组件内守卫
在路由将要跳转时,调用一个函数。
router/index.js
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| ... { name: 'message', path: 'message', component: Message, meta: {isAuth: true, title: "消息"} } ...
router.beforeEach((to, from, next) => { console.log(to, from) if(!to.meta.isAuth || localstorage.getItem('school') === 'atguigu') { next() } })
|
130 全局前置-路由守卫
在路由跳转完毕时,调用一个函数。
1 2 3
| router.afterEach((to, from) => { document.title = to.meta.title || 'XXX' })
|
131 独享路由守卫
直接在定义路由时设置路由守卫:
1 2 3 4 5 6 7 8 9
| { name: 'message', path: 'message', component: 'Message', meta: {isAuth: true, title: '消息'}, beforeEnter: (to, from, next) => { ... } }
|
132 组件内路由守卫
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| beforeRouteEnter(to,from, next) { console.log('About--beforeRouteEnter', to, from) if(to.meta.isAuth){ if(localstorage.getItem('school')==='atguigu') { next() } else { alert('学校名不对,无权限査看!') } else { next() } },
beforeRouteLeave(to, from, next) { console.log("About--beforeRouteLeave", to, from) next() }
|
133 history 模式与 hash 模式
Note
路由器的两种工作模式
- 对于一个 url 来说,什么是 hash 值?--
#
及其后面的内容就是 hash 值。
- hash 值不会包含在 HTTP 请求中,即:hash 值不会带给服务器。
- hash 模式:
- 地址中永远带着
#
号,不美观。
- 若以后将地址通过第三方手机 app 分享,若 app 校验严格,则地址会被标记为不合法。
- 兼容性较好。
- history 模式:
- 地址干净,美观
- 兼容性和 hash 模式相比略差。
- 应用部署上线时需要后端人员支持,解决刷新页面服务端 404 的问题(
connect-history-api-fallback
)。
在定义路由器时可以选择是 history 模式还是 hash 模式:
1 2 3 4
| const router = new VueRouter({ mode: 'history', ... })
|
134-135 element-ui
看文档慢慢来吧。